﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace DaedalusEngine.Source
{
    public class FrameAnimation : ICloneable
    {
        #region Fields

        private Rectangle initialFrameRectangle;        //Source rect of first frame of animation
        private int frameCount = 1;                     //Total frame count of the animation
        private int currentFrame = 0;                   //Index of the current frame being displayed
        private float frameLength = 0.0f;               //Length of time each frame should be displayed for
        private float frameTimer = 0.0f;                //Timer variable used to update the animation
        private int playCount = 0;                      //Amount of time the animation has been played
        private string nextAnimation = null;            //The name of the animation to be displayed following this

        #endregion

        #region Properties

        //Returns the source rectangle to display the current frame of the animation
        public Rectangle FrameRectangle
        {
            get
            {
                return new Rectangle(initialFrameRectangle.X + (initialFrameRectangle.Width * currentFrame),
                    initialFrameRectangle.Y, initialFrameRectangle.Width, initialFrameRectangle.Height);
            }
        }

        //Gets and sets the total frame count of the animation
        public int FrameCount
        {
            get { return frameCount; }
            set { frameCount = value; }
        }

        //Gets and sets the current frame value
        public int CurrentFrame
        {
            get { return currentFrame; }
            set
            {
                currentFrame = (int)MathHelper.Clamp(value, 0, frameCount - 1);
            }
        }

        //Gets and sets the time each frame should be displayed for
        public float FrameLength
        {
            get { return frameLength; }
            set { frameLength = value; }
        }

        //Gets and sets the total time the animation has played fully
        public int PlayCount
        {
            get { return playCount; }
            set { playCount = value; }
        }

        //Gets and sets the string for the next animation to be played
        public string NextAnimation
        {
            get { return nextAnimation; }
            set { nextAnimation = value; }
        }

        #endregion

        #region Constructor

        //Creates a new FrameAnimation
        public FrameAnimation(int x, int y, int width, int height, 
            int frames, float frameLength, string nextAnimation)
        {
            initialFrameRectangle = new Rectangle(x, y, width, height);
            FrameCount = frames;
            FrameLength = frameLength;
            NextAnimation = nextAnimation;
        }

        #endregion

        #region Methods

        //Updates the animation frame by frame
        public void Update(GameTime gameTime)
        {
            frameTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (frameTimer > frameLength)
            {
                frameTimer = 0.0f;

                currentFrame = (currentFrame + 1) % frameCount;
                if (currentFrame == 0)
                    playCount = (int)Math.Min(playCount + 1, int.MaxValue);
            }
        }

        public override string ToString()
        {
            return base.ToString();
        }

        //Returns a cloned instance of the frame animation
        public object Clone()
        {
            return new FrameAnimation(this.initialFrameRectangle.X, this.initialFrameRectangle.Y,
                this.initialFrameRectangle.Width, this.initialFrameRectangle.Height, this.FrameCount, this.FrameLength,
                this.NextAnimation);
        }

        #endregion
    }
}
